package com.qingzhou.framework.aspect;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.dialect.impl.CommonsDialectImpl;
import com.mybatisflex.core.query.CPI;
import com.mybatisflex.core.query.QueryTable;
import com.mybatisflex.core.query.QueryWrapper;
import com.qingzhou.common.constants.UserConstant;
import com.qingzhou.common.utils.SecurityUtil;
import com.qingzhou.common.web.domain.LoginUser;
import com.qingzhou.common.web.domain.SysRole;
import com.qingzhou.common.web.domain.SysUser;
import jodd.util.ArraysUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class EdcDataPermissionDialect extends CommonsDialectImpl {
    private static final String[] ignore_edc_tables = new String[]{"edc_materials","edc_hospital_district"};
    @Override
    public String forSelectByQuery(QueryWrapper queryWrapper) {
        List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
        String string = PermissionHolder.getFlag();
        boolean isSkip = StrUtil.equalsIgnoreCase(string,"SKIP");
        if(isSkip || CollUtil.isEmpty(queryTables) || ArraysUtil.contains(ignore_edc_tables,queryTables.get(0).getName()) || !StrUtil.startWith(queryTables.get(0).getName(),"edc_")) {
            return super.buildSelectSql(queryWrapper);
        }

        String tableName = queryTables.get(0).getName();
        LoginUser loginUser = SecurityUtil.getLoginUser();
        if (ObjectUtil.isNotNull(loginUser)) {
            SysUser sysUser = loginUser.getSysUser();
            // 如果是超级管理员，则不过滤数据
            if (ObjectUtil.isNotNull(sysUser) && !SecurityUtil.isAdmin(loginUser.getUserid())) {
                queryWrapper
                        .leftJoin("sys_user").as("u").on("u.user_name = "+tableName+".create_by")
                        .leftJoin("sys_dept").as("d").on("u.dept_id = d.dept_id");
                StringBuilder sqlString = new StringBuilder();
                List<String> conditions = new ArrayList<>();
                for (SysRole sysRole : sysUser.getRoles()) {
                    String ds = sysRole.getDataScope();
                    if (!UserConstant.DATA_SCOPE_CUSTOM.equals(ds) && conditions.contains(ds)) {
                        continue;
                    }
                    if (UserConstant.DATA_SCOPE_ALL.equals(ds)) {
                        sqlString = new StringBuilder();
                        conditions.add(ds);
                        break;
                    } else if (UserConstant.DATA_SCOPE_CUSTOM.equals(ds)) {
                        sqlString.append(StrUtil.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", UserConstant.DATA_SCOPE_ALIAS_DEPT, sysRole.getRoleId()));
                    } else if (UserConstant.DATA_SCOPE_DEPT.equals(ds)) {
                        sqlString.append(StrUtil.format(" OR {}.dept_id = {} ", UserConstant.DATA_SCOPE_ALIAS_DEPT, sysUser.getDeptId()));
                    } else if (UserConstant.DATA_SCOPE_DEPT_AND_CHILD.equals(ds)) {
                        sqlString.append(StrUtil.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", UserConstant.DATA_SCOPE_ALIAS_DEPT, sysUser.getDeptId(), sysUser.getDeptId()));
                    } else if (UserConstant.DATA_SCOPE_SELF.equals(ds)) {
                        sqlString.append(StrUtil.format(" OR {}.user_name = '{}' ", UserConstant.DATA_SCOPE_ALIAS_USER, sysUser.getUserName()));
                    }
                    conditions.add(ds);
                }
                queryWrapper.and(sqlString.substring(4));
            }
        }

        return super.buildSelectSql(queryWrapper);
    }
}
